// 文件：ApkSigner.java
package net.yyge.apksigner.signer;

import net.yyge.apksigner.android.apksig.SignWrapper;
import net.yyge.apksigner.android.kit.ApkSignerTool;
import net.yyge.apksigner.signer.utils.KeyStoreHelper;

import java.io.*;
import java.nio.file.Files;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

/**
 * APK 签名工具类，支持：
 * - 使用 .pk8 + .pem 证书文件签名（release/debug）
 * - 使用密钥库（JKS/BKS）签名
 * - 可配置 V1/V2/V3/V4 签名方案
 */
public class ApkSigner {

    private final File unsignedApkFile;
    private final File signedApkFile;

    public boolean useDefaultSignatureVersion = true;
    public boolean v1SigningEnabled = true;
    public boolean v2SigningEnabled = true;
    public boolean v3SigningEnabled = true;
    public boolean v4SigningEnabled = false;

    /**
     * 构造函数
     *
     * @param unsignedApkFile 未签名的 APK 文件
     * @param signedApkFile   签名后的输出 APK 文件
     */
    public ApkSigner(File unsignedApkFile, File signedApkFile) {
        this.unsignedApkFile = unsignedApkFile;
        this.signedApkFile = signedApkFile;
    }

    /**
     * 使用 .pk8 和 .x509.pem 证书文件对 APK 进行签名（Release 模式）
     *
     * @param pk8File  私钥文件（DER 编码）
     * @param x509File 证书文件（PEM 格式）
     * @return 是否签名成功
     */
    public boolean signRelease(File pk8File, File x509File) {
        List<String> args = new ArrayList<>();
        args.add("sign");
        args.add("--in");
        args.add(unsignedApkFile.getAbsolutePath());
        args.add("--out");
        args.add(signedApkFile.getAbsolutePath());
        args.add("--key");
        args.add(pk8File.getAbsolutePath());
        args.add("--cert");
        args.add(x509File.getAbsolutePath());

        // 如果不使用默认签名版本，则添加签名选项
        if (!useDefaultSignatureVersion) {
            args.add("--v1-signing-enabled");
            args.add(String.valueOf(v1SigningEnabled));
            args.add("--v2-signing-enabled");
            args.add(String.valueOf(v2SigningEnabled));
            args.add("--v3-signing-enabled");
            args.add(String.valueOf(v3SigningEnabled));
            args.add("--v4-signing-enabled");
            args.add(String.valueOf(v4SigningEnabled));
        }

        try {
            ApkSignerTool.main(args.toArray(new String[0]));
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 使用密钥库（如 JKS）对 APK 进行签名
     *
     * @param keyFile        密钥库文件
     * @param password       密钥库密码
     * @param alias          别名
     * @param aliasPassword  别名密码（通常与密钥库密码相同）
     * @return 是否签名成功
     */
    public boolean signRelease(File keyFile, String password, String alias, String aliasPassword) {
        try {
            // 加载密钥库
            KeyStore keystore = KeyStoreHelper.loadKeyStore(keyFile, password.toCharArray());

            // 获取私钥和证书链
            PrivateKey privateKey = (PrivateKey) keystore.getKey(alias, aliasPassword.toCharArray());
            X509Certificate cert = (X509Certificate) keystore.getCertificate(alias);

            if (privateKey == null || cert == null) {
                System.err.println("Error: Cannot find key or certificate for alias: " + alias);
                return false;
            }

            // 构建签名器配置
            SignWrapper.SignerConfig signerConfig = new SignWrapper.SignerConfig.Builder(
                "CERT",
                privateKey,
                List.of(cert)
            ).build();

            // 构建 ApkSigner
            SignWrapper apkSigner = new SignWrapper.Builder(List.of(signerConfig))
                .setInputApk(unsignedApkFile)
                .setOutputApk(signedApkFile)
                .setV1SigningEnabled(useDefaultSignatureVersion || v1SigningEnabled)
                .setV2SigningEnabled(useDefaultSignatureVersion || v2SigningEnabled)
                .setV3SigningEnabled(useDefaultSignatureVersion || v3SigningEnabled)
                .setV4SigningEnabled(useDefaultSignatureVersion || v4SigningEnabled)
                .build();

            // 执行签名
            apkSigner.sign();
            return true;

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 使用内置的 debug 密钥（testkey.pk8 + testkey.x509.pem）对 APK 进行签名
     *
     * @return 是否签名成功
     */
    public boolean signDebug() {
        File pk8File = null;
        File x509File = null;

        try {
            // 创建临时文件用于存放 debug 密钥
            pk8File = File.createTempFile("testkey", "pk8");
            x509File = File.createTempFile("testkey", "x509.pem");

            // 从资源目录读取内置密钥
            try (InputStream is = ApkSigner.class.getResourceAsStream("/keystore/testkey.pk8")) {
                if (is == null) {
                    throw new IOException("Resource /keystore/testkey.pk8 not found.");
                }
                Files.copy(is, pk8File.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
            }

            try (InputStream is = ApkSigner.class.getResourceAsStream("/keystore/testkey.x509.pem")) {
                if (is == null) {
                    throw new IOException("Resource /keystore/testkey.x509.pem not found.");
                }
                Files.copy(is, x509File.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
            }

            // 构建命令行参数
            List<String> args = new ArrayList<>();
            args.add("sign");
            args.add("--in");
            args.add(unsignedApkFile.getAbsolutePath());
            args.add("--out");
            args.add(signedApkFile.getAbsolutePath());
            args.add("--key");
            args.add(pk8File.getAbsolutePath());
            args.add("--cert");
            args.add(x509File.getAbsolutePath());

            if (!useDefaultSignatureVersion) {
                args.add("--v1-signing-enabled");
                args.add(String.valueOf(v1SigningEnabled));
                args.add("--v2-signing-enabled");
                args.add(String.valueOf(v2SigningEnabled));
                args.add("--v3-signing-enabled");
                args.add(String.valueOf(v3SigningEnabled));
                args.add("--v4-signing-enabled");
                args.add(String.valueOf(v4SigningEnabled));
            }

            // 调用 ApkSignerTool 签名
            ApkSignerTool.main(args.toArray(new String[0]));
            return true;

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            // 确保临时文件被删除
            if (pk8File != null && pk8File.exists()) {
                pk8File.delete();
            }
            if (x509File != null && x509File.exists()) {
                x509File.delete();
            }
        }
    }

    /**
     * 验证密钥库密码是否正确
     *
     * @param keyFile  密钥库文件
     * @param password 密码
     * @return 密码是否正确
     */
    public boolean validateKeystorePassword(File keyFile, String password) {
        return KeyStoreHelper.validateKeystorePassword(keyFile, password);
    }
}